﻿/*
 * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
 */

#ifndef WIFIBURNCTRL_H
#define WIFIBURNCTRL_H

#include <QObject>
#include "BurnCtrl.h"
#include "SecureLink/Channel.h"
#include "BurnToolCommon/Global.h"

#define NEXT_ACTION_ERASE_ALL 1
#define NEXT_ACTION_RESET 2

class WifiBurnCtrl : public BurnCtrl {
    Q_OBJECT
public:
    explicit WifiBurnCtrl(ChipType type = ChipType::WIFI5GNB, QObject *parent = nullptr);
    virtual ~WifiBurnCtrl() override;
    void ProcessReceiveData(PBYTE data, unsigned int &dataLen) override;
    void HandleChangeBaud(unsigned int &dataLen, PBYTE data);
    void HandleZeroAck(unsigned int &dataLen, PBYTE data);
    void HandleWaitStartC(unsigned int &dataLen, PBYTE data);
    void HandleFlashShakeHandsAck(unsigned int &dataLen, PBYTE data, int interFlagSize);
    void HandleWaitInitAck(unsigned int &dataLen, PBYTE data);
    void PartOfHandleWaitInitAck();
    void ResetData(unsigned int &dataLen, PBYTE data) const;
    void HandleWaitInitAckSub();
    void HandleSeloadDownAck(unsigned int &dataLen, PBYTE data);
    void ResetFsm2StartC();
    void HandleMulFsmAck(unsigned int& dataLen, PBYTE data);
    void HandleMulFsmAckSub();
    void HandleMulFsmAckP1(QString &strData, SEBOOT_ACK_FRAME &chlPktHead);
    void HandleMulFsmAckUploadEndAck(QString &strData, SEBOOT_ACK_FRAME &chlPktHead);
    void HandleInterAck(unsigned int& dataLen, PBYTE data);
    void HandleInterAckP2();
    void HandleInterAckP1();
    void HandleInterAckP1Sub(const UINT &nBytesRead, const BIN_INFO &info);
    void HandleSeloadUploadAck(unsigned int& dataLen, PBYTE data);
    void HandleUploadStartC(unsigned int& dataLen, PBYTE data);
    void HandleUploadInitAck(unsigned int& dataLen, PBYTE data);
    bool HandleUploadInitAckP2(unsigned int& dataLen, PBYTE data);
    bool HandleUploadInitAckP1(unsigned int& dataLen, PBYTE data);
    bool HandleUploadInitAckP3(unsigned int& dataLen, PBYTE data);
    void HandleUploadEotC(unsigned int& dataLen, PBYTE data);
    void SendCtrl() override;
    void SendCtrlSub(const BurnCmdType &type);
    virtual void StartConnectSetting() override;
    void InitBurnCmd() override;
    void AddCmdByInfo(BIN_INFO info, bool &isEraseAll, QMap<int, BIN_INFO> &infoArray);
    U32 SendBurnCmd() override;
    U32 StartBurn() override;
    void ResetUIAndFSM() override;
    void SetEraseMode(int eraseMode) override;
    void SetOnlyEraseAll(bool eraseAll) override;
    void StartUpload(QString output, U32 addr, U32 size) override;
    void ReadEfuse(U32 addr, U32 size) override;
    void YmodemPrepareIntialPacket(PBYTE &pBurnFileInfo, int &pktLen) override;
    void ResetByCmd() override;
    void AtReset(QString cmd) override;
    void SwitchToDfu() override;
    void EraseAllByCmd() override;
    void SetProgressRange() override;
    void UpdateProgress(UINT progress) override;
    void UpdateProgress(U32 fileSize, UINT totalWifiFileSize = 0);
    void ProceSeloaderEndAck(QString &strData, const SEBOOT_ACK_FRAME &chlPktHead);
    void ProceIfConnect();
    void ProceShakeHand();
    void TimeoutProcess() override;
    void ReadEfuseSendPayload(QString &strWifiSendData);
protected slots:
    long int SlotCommunication(WPARAM srcData, LPARAM srcLen) override;
    long int SlotCommunicationSub(PBYTE &data, bool &isConnecting, unsigned int len);
protected:
    void InitBurnCmdByArray(const QMap<int, BIN_INFO> &infoArray) override;
    QFile m_uploadFile;
    U32 m_packetSize;
    U32 m_resSize;
    int cCount;
    bool isPrePacket;
    int countTimeOut;
    unsigned int ackTimestamp;
private:
    U32 HandleEndCmd();
    void ReceiveDataMulFsm(PBYTE data, unsigned int &dataLen);
    void ParseData2CString(bool isConnecting);
    void ParseData2CStringSub(QString &strReceiveChar);
    void HandleImageOTP(const BIN_INFO &info);
    void HandleImageVer(const BIN_INFO &info);
    void HandleImageFactory(const BIN_INFO &info, bool &isEraseAll);
    void HandleImageKVNV(const BIN_INFO &info, bool &isEraseAll);
    void HandleImageOthers(const BIN_INFO &info, bool &isEraseAll);
    void HandleInterAckSetBinFilePos(BIN_INFO &info, U32 readBytesAckP2);
    void HandleFinalAck(unsigned int &dataLen, PBYTE data);
    void HandleInterAckSetBinFilePosEncrypt(BIN_INFO &info, U32 readBytesAckP2);
    void HandleWaitInitAckRead(const BIN_INFO &info, U32 &readBytes, UINT &nBytesRead, PBYTE pBurnFile);
};

#endif
